home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #4 / Amiga Plus CD - 2000 - No. 4.iso / Tools / Dev / Orbit_SRC / target.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-27  |  11.6 KB  |  538 lines

  1. /*
  2.     Amiga port by Oliver Gantert
  3.  
  4.     27.04.2000 - fixed some compiler warnings
  5. */
  6. /*
  7.  
  8. ORBIT, a freeware space combat simulator
  9. Copyright (C) 1999  Steve Belczyk <steve1@genesis.nred.ma.us>
  10.  
  11. This program is free software; you can redistribute it and/or
  12. modify it under the terms of the GNU General Public License
  13. as published by the Free Software Foundation; either version 2
  14. of the License, or (at your option) any later version.
  15.  
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. GNU General Public License for more details.
  20.  
  21. You should have received a copy of the GNU General Public License
  22. along with this program; if not, write to the Free Software
  23. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  24.  
  25. */
  26.  
  27. #include "orbit.h"
  28.  
  29. void InitTargets()
  30. /*
  31.  *  Set up targets
  32.  */
  33. {
  34.   int t;
  35.  
  36.   for (t=0; t<NTARGETS; t++)
  37.   {
  38.     target[t].age = target[t].msl_idle = 0.0;
  39.     target[t].vel[0] = target[t].vel[1] = target[t].vel[2] = 0.0;
  40.  
  41.     target[t].hidden = 0;
  42.     target[t].friendly = 0;
  43.     target[t].invisible = 0;
  44.  
  45.     target[t].move_forward = target[t].move_backward =
  46.     target[t].move_up = target[t].move_down =
  47.     target[t].move_pitchleft = target[t].move_pitchright =
  48.     target[t].move_left = target[t].move_right = 0.0;
  49.  
  50.     target[t].weapon = NPLAYER_WEAPONS;
  51.     target[t].shields = 100.0;
  52.     target[t].maxshields = 100.0;
  53.  
  54.     strcpy (target[t].name, "Sparky");
  55.   }
  56. }
  57.  
  58. int FindTarget()
  59. /*
  60.  *  Find an unsed target
  61.  */
  62. {
  63.   int i, oldest;
  64.   double maxage;
  65.  
  66.   for (i=0; i<NTARGETS; i++)
  67.   {
  68.     if (target[i].age == 0.0) return (i);
  69.  
  70.     if (i == 0)
  71.     {
  72.       oldest = i;
  73.       maxage = target[i].age;
  74.     }
  75.     else
  76.     {
  77.       if (target[i].age > maxage)
  78.       {
  79.         maxage = target[i].age;
  80.         oldest = i;
  81.       }
  82.     }
  83.   }
  84.  
  85.   return (oldest);
  86. }
  87.  
  88. int FindTargetByName (char *name)
  89. {
  90.   int t;
  91.  
  92.   for (t=0; t<NTARGETS; t++)
  93.   {
  94.     if ( (target[t].age > 0.0) &&
  95.     (!strcasecmp (name, target[t].name)) )
  96.     {
  97.       return (t);
  98.     }
  99.   }
  100.  
  101.   return (-1);
  102. }
  103.  
  104. void PlaceTarget (double x, double y, double z)
  105. /*
  106.  *  Put a brand new target somewhere
  107.  */
  108. {
  109.   int t;
  110.  
  111.   t = FindTarget();
  112.  
  113.   target[t].pos[0] = x;
  114.   target[t].pos[1] = y;
  115.   target[t].pos[2] = z;
  116.  
  117.   target[t].view[0] = 1.0;
  118.   target[t].view[1] = target[t].view[2] = 0.0;
  119.  
  120.   target[t].up[0] = 0.0;
  121.   target[t].up[1] = 0.0;
  122.   target[t].up[2] = 1.0;
  123.  
  124.   Crossp (target[t].right, target[t].up, target[t].view);
  125.  
  126.   if (deltaT == 0.0)
  127.   {
  128.     target[t].age = 0.1;
  129.   }
  130.   else
  131.   {
  132.     target[t].age = deltaT;
  133.   }
  134.  
  135.   target[t].msl_idle = 0.0;
  136.  
  137.   target[t].vel[0] = target[t].vel[1] = target[t].vel[2] = 0.0;
  138.  
  139.   target[t].move_forward = target[t].move_backward =
  140.   target[t].move_up = target[t].move_down =
  141.   target[t].move_pitchleft = target[t].move_pitchright =
  142.   target[t].move_left = target[t].move_right = 0.0;
  143.  
  144.   strcpy (target[t].name, "Target");
  145.   target[t].list = model[0].list;
  146. }
  147.  
  148. void PlaceRandomTarget()
  149. /*
  150.  *  Put a target somewhere reasonable, randomly
  151.  */
  152. {
  153.   double x, y, z, th;
  154.  
  155.   th = 2.0 * rnd (6.28);
  156.  
  157.   x = planet[3].pos[0] + 2.0 * planet[3].radius * sin (th);
  158.   y = planet[3].pos[1] + 2.0 * planet[3].radius * cos (th);
  159.   z = planet[3].pos[2];
  160.  
  161.   PlaceTarget (x, y, z);
  162. }
  163.  
  164. void DestroyTarget (int t)
  165. /*
  166.  *  Destroy specified target
  167.  */
  168. {
  169.   int e;
  170.  
  171.   target[t].age = 0.0;
  172.  
  173.   player.score += target[t].score;
  174.  
  175.   /* If this was the locked target, unset lock */
  176.   CheckLock();
  177.  
  178.   /* Check to see if destroying this target triggers an event */
  179.   for (e=0; e<NEVENTS; e++)
  180.   {
  181.     if (event[e].pending &&
  182.     event[e].enabled &&
  183.     (event[e].trigger == EVENT_DESTROY) &&
  184.     (!strcasecmp (event[e].cvalue, target[t].name)) )
  185.     {
  186.       EventAction (e);
  187.     }
  188.   }
  189. }
  190.  
  191. static float lmodel_ambient[] = {
  192.   0.1, 0.1, 0.1, 1.0 }
  193. ;
  194.  
  195. void DrawTargets ()
  196. /*
  197.  *  Draw all the targets
  198.  */
  199. {
  200.   int i;
  201.  
  202.   glShadeModel (GL_FLAT);
  203.  
  204.   /* Need some ambient light for targets */
  205.   glLightfv (GL_LIGHT0, GL_AMBIENT, lmodel_ambient);
  206.  
  207.   for (i=0; i<NTARGETS; i++)
  208.   {
  209.     if (target[i].age > 0.0) DrawTarget (i);
  210.   }
  211.  
  212.   glShadeModel (GL_SMOOTH);
  213. }
  214.  
  215. void DrawTarget (int i)
  216. /*
  217.  *  Draw this target
  218.  */
  219. {
  220.   double v[3]; 
  221.  
  222.   /* Bump this target's age */
  223.   target[i].age += deltaT;
  224.  
  225.   /* Forget it if target is hidden or invisible */
  226.   if (target[i].hidden || target[i].invisible) return;
  227.  
  228.   /* Don't bother if target is too far away */
  229.   if (target[i].range2 > TARG_MAXRANGE2) return;
  230.  
  231.   /* Bail if couldn't load model */
  232.   if (target[i].model == (-1)) return;
  233.  
  234.   glPushMatrix();
  235.  
  236.   Vsub (v, target[i].pos, player.pos);
  237.   glTranslated (v[0], v[1], v[2]);
  238.  
  239.   /* Show up vector */
  240.   /* glDisable (GL_LIGHTING);
  241.  glColor3f (0.0, 1.0, 0.0);
  242.  glBegin (GL_LINES);
  243.  glVertex3f (0.0, 0.0, 0.0);
  244.  glVertex3dv (target[i].up);
  245.  glEnd();
  246.  glEnable (GL_LIGHTING); */
  247.  
  248.   /* Have target look in proper direction */
  249.   LookAt (target[i].view, target[i].up);
  250.  
  251.   /* Draw it */
  252.   glCallList (target[i].list);
  253.  
  254.   /* Draw bounding box */
  255.   /* if (i == lock.target)
  256.  {
  257.   m = target[i].model;
  258.  
  259.   glDisable (GL_LIGHTING);
  260.   glColor3f (1.0, 1.0, 0.0);
  261.   glScaled (model[m].hibound[0] - model[m].lobound[0],
  262.          model[m].hibound[1] - model[m].lobound[1],
  263.       model[m].hibound[2] - model[m].lobound[2]);
  264.   glutWireCube (1.0);
  265.   glEnable (GL_LIGHTING);
  266.  }
  267. */
  268.   glPopMatrix();
  269. }
  270.  
  271. void MoveTargets()
  272. /*
  273.  *  Move all the targets
  274.  */
  275. {
  276.   int t;
  277.   double v[3];
  278.  
  279.   for (t=0; t<NTARGETS; t++)
  280.   {
  281.     if (target[t].age > 0.0)
  282.     {
  283.       /* Determine distance from player */
  284.       Vsub (v, target[t].pos, player.pos);
  285.       target[t].range2 = Mag2 (v);
  286.  
  287.       if (!target[t].hidden)
  288.       {
  289.         target[t].age += deltaT;
  290.         target[t].msl_idle += deltaT;
  291.  
  292.         /* Give this target a chance to think */
  293.         if (target[t].range2 < TARG_MAXRANGE2) ThinkTarget (t);
  294.  
  295.         /* Now move it */
  296.         MoveTarget (t);
  297.       }
  298.     }
  299.   }
  300. }
  301.  
  302. void MoveTarget (int t)
  303. /*
  304.  *  Move this target
  305.  */
  306. {
  307.   double deltav[3], v[3], theta; 
  308.   int p;
  309.  
  310.   /* Is this a network game and this target is us? */
  311.   /*
  312.  if (am_client && (t == client[clientme.client].target)) return;
  313.  if (am_server && (t == client[server.client].target)) return;
  314. */
  315.   /* Compute angle to move, given time change */
  316.   theta = THETA * deltaT;
  317.  
  318.   /* Deltav will be change in velocity components due to thrust */
  319.   deltav[0] = deltav[1] = deltav[2] = 0.0;
  320.  
  321.   if (target[t].move_left > 0.0)
  322.   {
  323.     RotateAbout (v, target[t].view, target[t].up, -theta*target[t].move_left);
  324.     Vset (target[t].view, v);
  325.     Normalize (target[t].view);
  326.     Crossp (target[t].right, target[t].up, target[t].view);
  327.     Normalize (target[t].right);
  328.   }
  329.  
  330.   if (target[t].move_right > 0.0)
  331.   {
  332.     RotateAbout (v, target[t].view, target[t].up, theta*target[t].move_right);
  333.     Vset (target[t].view, v);
  334.     Normalize (target[t].view);
  335.     Crossp (target[t].right, target[t].up, target[t].view);
  336.     Normalize (target[t].right);
  337.   }
  338.  
  339.   if (target[t].move_up > 0.0)
  340.   {
  341.     RotateAbout (v, target[t].view, target[t].right, theta*target[t].move_up);
  342.     Vset (target[t].view, v);
  343.     Normalize (target[t].view);
  344.     Crossp (target[t].up, target[t].view, target[t].right);
  345.     Normalize (target[t].up);
  346.   }
  347.  
  348.   if (target[t].move_down > 0.0)
  349.   {
  350.     RotateAbout (v, target[t].view, target[t].right, -theta*target[t].move_down);
  351.     Vset (target[t].view, v);
  352.     Normalize (target[t].view);
  353.     Crossp (target[t].up, target[t].view, target[t].right);
  354.     Normalize (target[t].up);
  355.   }
  356.  
  357.   if (target[t].move_pitchright > 0.0)
  358.   {
  359.     RotateAbout (v, target[t].up, target[t].view, -theta*target[t].move_pitchright);
  360.     Vset (target[t].up, v);
  361.     Normalize (target[t].up);
  362.     Crossp (target[t].right, target[t].up, target[t].view);
  363.     Normalize (target[t].right);
  364.   }
  365.  
  366.   if (target[t].move_pitchleft > 0.0)
  367.   {
  368.     RotateAbout (v, target[t].up, target[t].view, theta*target[t].move_pitchleft);
  369.     Vset (target[t].up, v);
  370.     Normalize (target[t].up);
  371.     Crossp (target[t].right, target[t].up, target[t].view);
  372.     Normalize (target[t].right);
  373.   }
  374.  
  375.   if (target[t].move_forward > 0.0)
  376.   {
  377.     Vmul (v, target[t].view, target[t].move_forward*DELTAV*deltaT);
  378.     Vadd (deltav, deltav, v);
  379.   }
  380.  
  381.   if (target[t].move_backward > 0.0)
  382.   {
  383.     Vmul (v, target[t].view, -target[t].move_backward*DELTAV*deltaT);
  384.     Vadd (deltav, deltav, v);
  385.   }
  386.  
  387.   /* Compute change to velocity */
  388.   Vadd (target[t].vel, target[t].vel, deltav);
  389.  
  390.   /* Compute gravity's contribution */
  391.   if (gravity && (am_client || am_server))
  392.   {
  393.     Gravity (deltav, target[t].pos);
  394.     Vadd (target[t].vel, target[t].vel, deltav);
  395.   }
  396.  
  397.   /* Finaly, move target */
  398.   Vmul (v, target[t].vel, deltaT);
  399.   Vadd (target[t].pos, target[t].pos, v);
  400.  
  401.   target[t].move_forward = target[t].move_backward = 0.0;
  402.  
  403.   if ( (!am_client) && (!am_server) )
  404.   {
  405.     target[t].move_up = target[t].move_down =
  406.     target[t].move_pitchleft = target[t].move_pitchright =
  407.     target[t].move_left = target[t].move_right = 0.0;
  408.   }
  409.  
  410.   /* See if target[t] cratered on a planet */
  411.   if ((!am_client) && ((-1) != (p = InsidePlanet (target[t].pos))))
  412.   {
  413.     /* Make an explosion */
  414.     Vmul (v, target[t].pos, 1.05);
  415.     Boom (v, 1.0); 
  416.     if (am_server) 
  417.     {
  418.       NetTargetCratered (t, p); 
  419.     }
  420.     else 
  421.     {
  422.       DestroyTarget (t); 
  423.     }
  424.   }
  425.  
  426.   /* Regenerate target shields */
  427.   target[t].shields += target[t].shieldregen * deltaT;
  428.   if (target[t].shields > target[t].maxshields)
  429.   target[t].shields = target[t].maxshields;
  430. }
  431.  
  432. void TargetFiresMissile (int t)
  433. /*
  434.  *  Target t tries to fire missile at player
  435.  */
  436. {
  437.   if (target[t].msl_idle > weapon[target[t].weapon].idle)
  438.   {
  439.     /* Fire away! */
  440.     target[t].msl_idle = 0.0;
  441.     FireMissile (target[t].pos, target[t].vel, target[t].view,
  442.     target[t].friendly, target[t].weapon, t);
  443.   }
  444. }
  445.  
  446. void ShowTargetNames()
  447. {
  448.   int t;
  449.   char v, buf[128];
  450.   double v1[3];
  451.  
  452.   for (t=0; t<NTARGETS; t++)
  453.   {
  454.     if ( (target[t].age > 0.0) &&
  455.     (target[t].range2 < TARG_MAXRANGE2) &&
  456.     (!target[t].hidden) &&
  457.     (!target[t].invisible) )
  458.     {
  459.       if (target[t].friendly)
  460.       glColor3d (0.0, 0.8, 0.0);
  461.       else
  462.       glColor3d (0.8, 0.0, 0.0);
  463.  
  464.       Vsub (v1, target[t].pos, player.pos);
  465.       glRasterPos3dv (v1);
  466.       glGetBooleanv (GL_CURRENT_RASTER_POSITION_VALID, &v);
  467.       if (v)
  468.       {
  469.         if (target[t].range2 <= weapon[player.weapon].range2) 
  470.         {
  471.           sprintf (buf, "%s:%.0lf", target[t].name,  
  472.           KM_TO_UNITS1*sqrt(target[t].range2)); 
  473.         }
  474.         else 
  475.         {
  476.           strcpy (buf, target[t].name); 
  477.         }
  478.         Print (GLUT_BITMAP_HELVETICA_10, buf);
  479.       }
  480.     }
  481.   }
  482. }
  483.  
  484. int HitTarget (int m)
  485. /*
  486.  *  See if missile m hit any target.  -1 if not.
  487.  */
  488. {
  489.   int t, mdl, valid;
  490.   double v1[3], d;
  491.  
  492.   /* Loop through targets */
  493.   for (t=0; t<NTARGETS; t++)
  494.   {
  495.     /* See if we should even check this target */
  496.     if (!am_client && !am_server)
  497.     {
  498.       valid = (target[t].age > 0.0) &&
  499.       (!target[t].hidden) &&
  500.       (msl[m].friendly != target[t].friendly);
  501.     }
  502.     else
  503.     {
  504.       valid = (target[t].age > 0.0) &&
  505.       (!target[t].hidden) &&
  506.       (t != msl[m].owner);
  507.     }
  508.  
  509.     if (valid)
  510.     {
  511.       /* Get coords relative to target */
  512.       Vsub (v1, msl[m].pos, target[t].pos);
  513.  
  514.       /* Get target's model */
  515.       mdl = target[t].model;
  516.  
  517.       /* Check each axis by projecting v1 and checking bounding box */
  518.       d = Dotp (v1, target[t].view);
  519.       if ( (d < model[mdl].lobound[0]) ||
  520.       (d > model[mdl].hibound[0]) ) continue;
  521.  
  522.       d = Dotp (v1, target[t].right);
  523.       if ( (d < model[mdl].lobound[1]) ||
  524.       (d > model[mdl].hibound[1]) ) continue;
  525.  
  526.       d = Dotp (v1, target[t].up);
  527.       if ( (d < model[mdl].lobound[2]) ||
  528.       (d > model[mdl].hibound[2]) ) continue;
  529.  
  530.       /* If we get here, it's a hit! */
  531.       return (t);
  532.     }
  533.   }
  534.  
  535.   /* Nope */
  536.   return (-1);
  537. }
  538.